﻿using Desktop.Interfaces;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows;
using System;

namespace Desktop.Controls
{
    public class Workspace : TabControl, IWorkspace, INotifyPropertyChanged
    {
        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        public static readonly RoutedEvent ClosingEvent =
            EventManager.RegisterRoutedEvent("Closing", RoutingStrategy.Bubble,
                typeof(RoutedEventHandler), typeof(Workspace));

        public static readonly RoutedEvent CloseTabEvent =
            EventManager.RegisterRoutedEvent("CloseTab", RoutingStrategy.Bubble,
                typeof(RoutedEventHandler), typeof(Workspace));

        public static readonly RoutedEvent PrincipalChangedEvent =
            EventManager.RegisterRoutedEvent("PrincipalChanged", RoutingStrategy.Bubble,
                typeof(RoutedEventHandler), typeof(Workspace));

        public event RoutedEventHandler Closing
        {
            add
            {
                AddHandler(ClosingEvent, value);
            }
            remove
            {
                RemoveHandler(ClosingEvent, value);
            }
        }

        public event RoutedEventHandler CloseTab
        {
            add
            {
                AddHandler(ClosingEvent, value);
            }
            remove
            {
                RemoveHandler(ClosingEvent, value);
            }
        }

        public event RoutedEventHandler PrincipalChanged
        {
            add
            {
                AddHandler(PrincipalChangedEvent, value);
            }
            remove
            {
                RemoveHandler(PrincipalChangedEvent, value);
            }
        }

        #endregion

        #region Constants

        private const string DEFAULT_NAME = "Workspace";

        #endregion

        #region Variables

        private IApplication _parent;
        private string _workspaceName;
        private bool _isCloseable;
        private BindingList<IActivity> _activities;

        #endregion

        #region Constructors

        public Workspace(IApplication parent)
            : base()
        {
            TabStripPlacement = Dock.Left;

            AddHandler(WorkspaceTabItem.CloseTabEvent, new RoutedEventHandler(OnCloseTab));
            AddHandler(Workspace.CloseTabEvent, new RoutedEventHandler(OnCloseTab));
            AddHandler(Workspace.ClosingEvent, new RoutedEventHandler(OnClosing));
            AddHandler(Workspace.PrincipalChangedEvent, new RoutedEventHandler(OnPrincipalChanged));

            WorkspaceName = DEFAULT_NAME;
            IsCloseable = true;
            Parent = parent;

            _activities = new BindingList<IActivity>();
            ItemsSource = _activities;
        }

        public Workspace()
            : this(null)
        {
        }

        #endregion

        #region Properties

        public string WorkspaceName
        {
            get
            {
                return _workspaceName;
            }
            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    value = DEFAULT_NAME;
                }
                if (_workspaceName != value)
                {
                    _workspaceName = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("WorkspaceName"));
                    }
                }
            }
        }

        public bool IsCloseable
        {
            get
            {
                return _isCloseable;
            }
            set
            {
                if (_isCloseable != value)
                {
                    _isCloseable = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("IsCloseable"));
                    }
                }
            }
        }

        public new IApplication Parent
        {
            get
            {
                return _parent;
            }
            set
            {
                _parent = value;
            }
        }

        #endregion

        #region Methods

        public void OpenActivity(IActivity activity)
        {
            activity.Parent = this;
            _activities.Add(activity);
            SelectedItem = activity;
        }

        public void CloseActivity(IActivity activity)
        {
            if (_activities.Contains(activity))
            {
                activity.Parent = null;
                int index = _activities.IndexOf(activity) - 1;
                _activities.Remove(activity);
                if (index >= 0)
                {
                    SelectedItem = _activities[index];
                }
            }
        }

        public void Close()
        {
            Parent.CloseWorkspace(this);
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new WorkspaceTabItem();
        }

        #endregion

        #region Event Handlers

        private void OnCloseTab(object source, RoutedEventArgs e)
        {
            ActivityBase activity;

            TabItem tabItem = e.OriginalSource as TabItem;
            if (tabItem != null)
            {
                activity = tabItem.DataContext as ActivityBase;
            }
            else
            {
                activity = e.OriginalSource as ActivityBase;
                //activity = (e.OriginalSource as Workspace).SelectedContent as ActivityBase;
            }

            activity.RaiseEvent(new RoutedEventArgs(ActivityBase.ClosingEvent, this));

            _activities.Remove(activity);
        }

        protected virtual void OnClosing(object source, RoutedEventArgs e)
        {
            // Close all activities:
            while (_activities.Count > 0)
            {
                ActivityBase activity = _activities[0] as ActivityBase;
                activity.RaiseEvent(new RoutedEventArgs(ActivityBase.ClosingEvent, activity));
                _activities.Remove(activity);
            }
        }

        protected virtual void OnPrincipalChanged(object source, RoutedEventArgs e)
        {
            List<IActivity> activities = new List<IActivity>(_activities);

            foreach (ActivityBase activity in activities)
            {
                activity.RaiseEvent(new RoutedEventArgs(ActivityBase.PrincipalChangedEvent, activity));
            }
        }

        #endregion
    }
}